package com.example.teaching_server.controller;

import com.example.teaching_server.common.ApiResponse;
import com.example.teaching_server.dto.ClassDTO;
import com.example.teaching_server.dto.GradeClassSimpleDTO;
import com.example.teaching_server.entity.ClassEntity;
import com.example.teaching_server.service.ClassService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.stream.Collectors;

@Slf4j
@RestController
@RequestMapping("/api/classes")
@RequiredArgsConstructor
@Tag(name = "班级管理", description = "班级信息查询和管理接口")
public class ClassController {
    private final ClassService classService;

    /**
     * 获取所有班级
     */
    @GetMapping
    @Operation(summary = "获取班级列表", description = "获取所有班级的详细信息")
    public ApiResponse<List<ClassDTO>> getAllClasses() {
        log.info("开始获取班级列表");

        try {
            List<ClassEntity> classes = classService.getAllClasses();
            List<ClassDTO> classDTOs = classes.stream()
                    .map(this::convertToDTO)
                    .collect(Collectors.toList());
            log.info("成功获取{}个班级", classDTOs.size());
            return ApiResponse.success("班级列表获取成功", classDTOs);
        } catch (Exception e) {
            log.error("获取班级列表失败", e);
            return ApiResponse.fail("获取班级列表失败: " + e.getMessage());
        }
    }

    /**
     * 获取班级选项
     */
    @GetMapping("/options")
    @Operation(summary = "获取班级选项", description = "获取用于下拉选择的班级选项列表")
    public ApiResponse<List<ClassOptionDTO>> getClassOptions() {
        log.info("开始获取班级选项");

        try {
            List<ClassEntity> classes = classService.getAllClasses();
            List<ClassOptionDTO> options = classes.stream()
                    .map(this::convertToOptionDTO)
                    .collect(Collectors.toList());
            log.info("成功获取{}个班级选项", options.size());
            return ApiResponse.success("班级选项获取成功", options);
        } catch (Exception e) {
            log.error("获取班级选项失败", e);
            return ApiResponse.fail("获取班级选项失败: " + e.getMessage());
        }
    }

    /**
     * 按年级获取班级
     */
    @GetMapping("/by-grade")
    @Operation(summary = "按年级获取班级", description = "根据年级级别筛选班级列表")
    public ApiResponse<List<ClassDTO>> getClassesByGrade(
            @Parameter(description = "年级级别")
            @RequestParam String gradeLevel) {
        log.info("开始按年级获取班级: gradeLevel={}", gradeLevel);

        try {
            List<ClassEntity> classes = classService.getClassesByGrade(gradeLevel);
            List<ClassDTO> classDTOs = classes.stream()
                    .map(this::convertToDTO)
                    .collect(Collectors.toList());
            log.info("成功获取{}年级的{}个班级", gradeLevel, classDTOs.size());
            return ApiResponse.success(gradeLevel + "班级列表获取成功", classDTOs);
        } catch (Exception e) {
            log.error("按年级获取班级失败: gradeLevel={}", gradeLevel, e);
            return ApiResponse.fail("获取班级列表失败: " + e.getMessage());
        }
    }

    /**
     * 获取所有年级列表
     */
    @GetMapping("/grades")
    @Operation(summary = "获取年级列表", description = "获取所有可用的年级级别列表")
    public ApiResponse<List<String>> getAllGradeLevels() {
        log.info("开始获取年级列表");

        try {
            List<String> gradeLevels = classService.getAllGradeLevels();
            log.info("成功获取{}个年级", gradeLevels.size());
            return ApiResponse.success("年级列表获取成功", gradeLevels);
        } catch (Exception e) {
            log.error("获取年级列表失败", e);
            return ApiResponse.fail("获取年级列表失败: " + e.getMessage());
        }
    }

    /**
     * 获取老师班级列表
     */
    @GetMapping("/by-teacher")
    @Operation(summary = "获取老师班级列表", description = "根据老师ID获取其负责的班级列表")
    public ApiResponse<List<GradeClassSimpleDTO>> getTeacherClassList(
            @Parameter(description = "老师ID")
            @RequestParam Long teacherId) {
        log.info("开始获取老师班级列表: teacherId={}", teacherId);

        try {
            List<GradeClassSimpleDTO> teacherClasses = classService.getTeacherClassList(teacherId);
            log.info("成功获取老师{}的{}个班级", teacherId, teacherClasses.size());
            return ApiResponse.success("老师班级列表获取成功", teacherClasses);
        } catch (Exception e) {
            log.error("获取老师班级列表失败: teacherId={}", teacherId, e);
            return ApiResponse.fail("获取老师班级列表失败: " + e.getMessage());
        }
    }

    /**
     * 获取老师班级名称
     */
    @GetMapping("/teacher-class-names")
    @Operation(summary = "获取老师班级名称", description = "根据老师ID获取其负责的班级名称列表")
    public ApiResponse<List<String>> getTeacherClassNames(
            @Parameter(description = "老师ID")
            @RequestParam Long teacherId) {
        log.info("开始获取老师班级名称: teacherId={}", teacherId);

        try {
            List<String> classNames = classService.getTeacherClassNames(teacherId);
            log.info("成功获取老师{}的{}个班级名称", teacherId, classNames.size());
            return ApiResponse.success("老师班级名称列表获取成功", classNames);
        } catch (Exception e) {
            log.error("获取老师班级名称失败: teacherId={}", teacherId, e);
            return ApiResponse.fail("获取老师班级名称列表失败: " + e.getMessage());
        }
    }

    /**
     * 统一查询接口
     */
    @GetMapping("/search")
    @Operation(summary = "搜索班级", description = "根据年级和关键词搜索班级")
    public ApiResponse<List<ClassDTO>> searchClasses(
            @Parameter(description = "年级级别")
            @RequestParam(required = false) String gradeLevel,
            @Parameter(description = "搜索关键词")
            @RequestParam(required = false) String keyword) {
        log.info("开始搜索班级: gradeLevel={}, keyword={}", gradeLevel, keyword);

        try {
            List<ClassEntity> classes = classService.searchClassesByGradeAndKeyword(gradeLevel, keyword);
            List<ClassDTO> classDTOs = classes.stream()
                    .map(this::convertToDTO)
                    .collect(Collectors.toList());
            log.info("成功搜索到{}个班级", classDTOs.size());
            return ApiResponse.success("班级搜索成功", classDTOs);
        } catch (Exception e) {
            log.error("搜索班级失败: gradeLevel={}, keyword={}", gradeLevel, keyword, e);
            return ApiResponse.fail("搜索班级失败: " + e.getMessage());
        }
    }

    /**
     * 转换Entity到DTO
     */
    private ClassDTO convertToDTO(ClassEntity entity) {
        ClassDTO dto = new ClassDTO();
        dto.setClassId(entity.getClassId());
        dto.setClassName(entity.getClassName());
        dto.setGradeLevel(entity.getGradeLevel());
        dto.setHeadTeacher(entity.getHeadTeacher());
        dto.setStudentCount(entity.getStudentCount());
        return dto;
    }

    /**
     * 转换Entity到选项DTO
     */
    private ClassOptionDTO convertToOptionDTO(ClassEntity entity) {
        ClassOptionDTO option = new ClassOptionDTO();
        option.setClassId(entity.getClassId());
        option.setClassName(entity.getClassName());
        option.setDisplayName(generateDisplayName(entity));
        return option;
    }

    /**
     * 生成显示名称
     */
    private String generateDisplayName(ClassEntity entity) {
        StringBuilder displayName = new StringBuilder();

        if (entity.getGradeLevel() != null) {
            displayName.append(entity.getGradeLevel());
        }

        if (entity.getClassName() != null) {
            displayName.append(entity.getClassName());
        }

        if (displayName.isEmpty()) {
            displayName.append("未知班级");
        }

        return displayName.toString();
    }

    /**
     * 班级选项DTO
     */
    @Setter
    @Getter
    public static class ClassOptionDTO {
        private Long classId;
        private String className;
        private String displayName;

    }
}
